package EA.operators.selection;
import EA.*;
import RKUjava.util.RKUValuation;
import RKUjava.lang.RKUCloneable;


/** This class implements proportional selection with scaling of fitness.
    <br><blink><b>Notes:</b></blink>
    <ul>
    <li>If you want to clone the objects you must
    implement the interface RKUCloneable.
    </ul>
    <blink><font size=7><b>THIS CLASS IS NOT IMPLEMENTED YET!</b></font></blink>
*/
public class ScalingPropSelection extends Selection
{
private double[][] bounds;
private int theinputsize;
private double thec;

    /** Create a selection object. <br>
	Note: You should only use object instances if the length of
	the input array is constant, i.e., with constant population size.
	@param inputsize The number of input individuals.
	@param c A constant to add after range scaling. The selection pressure
	drops as c increases. E.g. if c=100 then the scaled ranges is 100 to
	101 with 100 assigned to the least fit individual.
    */
public ScalingPropSelection(int inputsize, double c)
    {
	super();

	thec = c;
	theinputsize = inputsize;
	bounds = new double[inputsize][2];
	
    }

  /** Perform a proportional selection among the sources. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. When using this method the object with
      highest va<lue is selected. Objects are NOT cloned.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
  */
  public Object[] objSelect(Object[] sources, int numberofselected)
  {
    return objSelectInto(sources, numberofselected, true, false, 0, sources.length, new Object[numberofselected]);
  }

  /** Perform a proportional selection among the sources. 
      Use this method when an instance 
      of the Selection object is used (e.g. for speed reasons).<br>

      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. Objects are NOT cloned.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
  */
  public Object[] objSelect(Object[] sources, int numberofselected, boolean maximization)
  {
    return objSelectInto(sources, numberofselected, maximization, false, 0, sources.length, new Object[numberofselected]);
  }

  /** Perform a proportional selection among the sources. 
      Use this method when an instance 
      of the Selection object is used (e.g. for speed reasons).<br>

      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. 
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param cloneobjects Boolean indicating whether you want to clone the 
      selected object. (Remember to implement cloneable)
  */
  public Object[] objSelect(Object[] sources, int numberofselected, boolean maximization, boolean cloneobjects)
    {
      return objSelectInto(sources, numberofselected, maximization, cloneobjects, 0, sources.length, new Object[numberofselected]);
    }

  /** Perform a selection among the sources in the chosen range. 
      Use this method when an instance 
      of the Selection object is used (e.g. for speed reasons).<br>

      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. Passing 0 in <tt>lowerindex</tt> and 
      sources.length in <tt>upperindex</tt> will perform a selection among all
      objects in the sources-array.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param cloneobjects Boolean indicating whether you want to clone the 
      selected object. (Remember to implement cloneable)
      @param lowerindex The lower index of the range.
      @param upperindex The upper index of the range + 1. 
  */
  public Object[] objSelect(Object[] sources, int numberofselected, boolean maximization, boolean cloneobjects, int lowerindex, int upperindex)
  {
      return objSelectInto(sources, numberofselected, maximization, cloneobjects, lowerindex, upperindex, new Object[numberofselected]);
  }

    /** Perform a selection among the sources and place the selected in an array. 
      Use this method when an instance 
      of the Selection object is used (e.g. for speed reasons).<br>

      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. When using this method the object with
      highest value is selected. Objects are NOT cloned.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param destination The array to place the selected in. MUST be big 
      enough to hold all entries.
      @return The array passed as <tt>destination</tt>.
  */
  public Object[] objSelectInto(Object[] sources, int numberofselected, Object[] destination)
    {
    return objSelectInto(sources, numberofselected, true, false, 0, sources.length, destination);
    };

  /** Perform a selection among the sources and place the selected in an array. 
      Use this method when an instance 
      of the Selection object is used (e.g. for speed reasons).<br>

      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. Objects are NOT cloned.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param destination The array to place the selected in. MUST be big 
      enough to hold all entries.
      @return The array passed as <tt>destination</tt>.
  */
  public Object[] objSelectInto(Object[] sources, int numberofselected, boolean maximization, Object[] destination) 
    {
	return objSelectInto(sources, numberofselected, maximization, false, 0, sources.length, destination);
    };

  /** Perform a selection among the sources and place the selected in an array. 
      Use this method when an instance 
      of the Selection object is used (e.g. for speed reasons).<br>

      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. 
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param cloneobjects Boolean indicating whether you want to clone the 
      selected object. (Remember to implement cloneable)
      @param destination The array to place the selected in. MUST be big 
      enough to hold all entries.
      @return The array passed as <tt>destination</tt>.
  */
  public Object[] objSelectInto(Object[] sources, int numberofselected, boolean maximization, boolean cloneobjects, Object[] destination) 
    {
      return objSelectInto(sources, numberofselected, maximization, cloneobjects, 0, sources.length, destination);
    };

  /** Perform a selection among the sources in the chosen range and place the selected in an array. 
      Use this method when an instance 
      of the Selection object is used (e.g. for speed reasons).<br>

      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. Passing 0 in <tt>lowerindex</tt> and 
      sources.length in <tt>upperindex</tt> will perform a selection among all
      objects in the sources-array.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param cloneobjects Boolean indicating whether you want to clone the 
      selected object. (Remember to implement cloneable)
      @param lowerindex The lower index of the range.
      @param upperindex The upper index of the range + 1. 
      @param destination The array to place the selected in. MUST be big 
      enough to hold all entries.
      @return The array passed as <tt>destination</tt>.
  */
  public Object[] objSelectInto(Object[] sources, int numberofselected, boolean maximization, boolean cloneobjects, int lowerindex, int upperindex, Object[] destination)
  {
    int i, index1, index2;
    int candidates;

    candidates = upperindex-lowerindex;

    if (maximization==true && cloneobjects==false) {
      for (i=0;i<numberofselected;i++) {
	index1 = lowerindex+UsefulRoutines.randomInt(candidates);
	index2 = lowerindex+UsefulRoutines.randomInt(candidates);
	if (((RKUValuation)sources[index1]).value()>=((RKUValuation)sources[index2]).value())
	  destination[i] = sources[index1];
	else
	  destination[i] = sources[index2];
      }
    }
    else if (maximization==true && cloneobjects==true) {
      for (i=0;i<numberofselected;i++) {
	index1 = lowerindex+UsefulRoutines.randomInt(candidates);
	index2 = lowerindex+UsefulRoutines.randomInt(candidates);
	if (((RKUValuation)sources[index1]).value()>=((RKUValuation)sources[index2]).value())
	  destination[i] = ((RKUCloneable)sources[index1]).clone();
	else
	  destination[i] = ((RKUCloneable)sources[index2]).clone();
      }
    }
    else if (maximization==false && cloneobjects==false) {
      for (i=0;i<numberofselected;i++) {
	index1 = lowerindex+UsefulRoutines.randomInt(candidates);
	index2 = lowerindex+UsefulRoutines.randomInt(candidates);
	if (((RKUValuation)sources[index1]).value()<=((RKUValuation)sources[index2]).value())
	  destination[i] = sources[index1];
	else
	  destination[i] = sources[index2];
      }
    }
    else if (maximization==false && cloneobjects==true) {
      for (i=0;i<numberofselected;i++) {
	index1 = lowerindex+UsefulRoutines.randomInt(candidates);
	index2 = lowerindex+UsefulRoutines.randomInt(candidates);
	if (((RKUValuation)sources[index1]).value()<=((RKUValuation)sources[index2]).value())
	  destination[i] = ((RKUCloneable)(sources[index1])).clone();
	else
	  destination[i] = ((RKUCloneable)(sources[index2])).clone();
      }
    }
    return destination;
    };












  /** Perform a proportional selection among the sources. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. When using this method the object with
      highest value is selected. Objects are NOT cloned.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
  */
  public static Object[] select(Object[] sources, int numberofselected)
  {
    return selectInto(sources, numberofselected, true, false, 0, sources.length, new Object[numberofselected]);
  }

  /** Perform a proportional selection among the sources. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. Objects are NOT cloned.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
  */
  public static Object[] select(Object[] sources, int numberofselected, boolean maximization)
  {
    return selectInto(sources, numberofselected, maximization, false, 0, sources.length, new Object[numberofselected]);
  }

  /** Perform a proportional selection among the sources. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. 
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param cloneobjects Boolean indicating whether you want to clone the 
      selected object. (Remember to implement cloneable)
  */
  public static Object[] select(Object[] sources, int numberofselected, boolean maximization, boolean cloneobjects)
    {
      return selectInto(sources, numberofselected, maximization, cloneobjects, 0, sources.length, new Object[numberofselected]);
    }

  /** Perform a selection among the sources in the chosen range. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. Passing 0 in <tt>lowerindex</tt> and 
      sources.length in <tt>upperindex</tt> will perform a selection among all
      objects in the sources-array.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param cloneobjects Boolean indicating whether you want to clone the 
      selected object. (Remember to implement cloneable)
      @param lowerindex The lower index of the range.
      @param upperindex The upper index of the range + 1. 
  */
  public static Object[] select(Object[] sources, int numberofselected, boolean maximization, boolean cloneobjects, int lowerindex, int upperindex)
  {
      return selectInto(sources, numberofselected, maximization, cloneobjects, lowerindex, upperindex, new Object[numberofselected]);
  }

    /** Perform a selection among the sources and place the selected in an array. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. When using this method the object with
      highest value is selected. Objects are NOT cloned.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param destination The array to place the selected in. MUST be big 
      enough to hold all entries.
      @return The array passed as <tt>destination</tt>.
  */
  public static Object[] selectInto(Object[] sources, int numberofselected, Object[] destination)
    {
    return selectInto(sources, numberofselected, true, false, 0, sources.length, destination);
    };

  /** Perform a selection among the sources and place the selected in an array. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. Objects are NOT cloned.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param destination The array to place the selected in. MUST be big 
      enough to hold all entries.
      @return The array passed as <tt>destination</tt>.
  */
  public static Object[] selectInto(Object[] sources, int numberofselected, boolean maximization, Object[] destination) 
    {
	return selectInto(sources, numberofselected, maximization, false, 0, sources.length, destination);
    };

  /** Perform a selection among the sources and place the selected in an array. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. 
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param cloneobjects Boolean indicating whether you want to clone the 
      selected object. (Remember to implement cloneable)
      @param destination The array to place the selected in. MUST be big 
      enough to hold all entries.
      @return The array passed as <tt>destination</tt>.
  */
  public static Object[] selectInto(Object[] sources, int numberofselected, boolean maximization, boolean cloneobjects, Object[] destination) 
    {
      return selectInto(sources, numberofselected, maximization, cloneobjects, 0, sources.length, destination);
    };

  /** Perform a selection among the sources in the chosen range and place the selected in an array. <br>
      <b>Note:</b> The source objects must implement the interface RKUValuation
      from the package RKUjava.util. Passing 0 in <tt>lowerindex</tt> and 
      sources.length in <tt>upperindex</tt> will perform a selection among all
      objects in the sources-array.
      @param sources The object to select between. 
      @param numberofselected The size of the resulting array.
      @param maximization Boolean indicating whether this is a maximization or
      minimization selection.
      @param cloneobjects Boolean indicating whether you want to clone the 
      selected object. (Remember to implement cloneable)
      @param lowerindex The lower index of the range.
      @param upperindex The upper index of the range + 1. 
      @param destination The array to place the selected in. MUST be big 
      enough to hold all entries.
      @return The array passed as <tt>destination</tt>.
  */
  public static Object[] selectInto(Object[] sources, int numberofselected, boolean maximization, boolean cloneobjects, int lowerindex, int upperindex, Object[] destination)
  {
    int i, index1, index2;
    int candidates;

    candidates = upperindex-lowerindex;

    if (maximization==true && cloneobjects==false) {
      for (i=0;i<numberofselected;i++) {
	index1 = lowerindex+UsefulRoutines.randomInt(candidates);
	index2 = lowerindex+UsefulRoutines.randomInt(candidates);
	if (((RKUValuation)sources[index1]).value()>=((RKUValuation)sources[index2]).value())
	  destination[i] = sources[index1];
	else
	  destination[i] = sources[index2];
      }
    }
    else if (maximization==true && cloneobjects==true) {
      for (i=0;i<numberofselected;i++) {
	index1 = lowerindex+UsefulRoutines.randomInt(candidates);
	index2 = lowerindex+UsefulRoutines.randomInt(candidates);
	if (((RKUValuation)sources[index1]).value()>=((RKUValuation)sources[index2]).value())
	  destination[i] = ((RKUCloneable)sources[index1]).clone();
	else
	  destination[i] = ((RKUCloneable)sources[index2]).clone();
      }
    }
    else if (maximization==false && cloneobjects==false) {
      for (i=0;i<numberofselected;i++) {
	index1 = lowerindex+UsefulRoutines.randomInt(candidates);
	index2 = lowerindex+UsefulRoutines.randomInt(candidates);
	if (((RKUValuation)sources[index1]).value()<=((RKUValuation)sources[index2]).value())
	  destination[i] = sources[index1];
	else
	  destination[i] = sources[index2];
      }
    }
    else if (maximization==false && cloneobjects==true) {
      for (i=0;i<numberofselected;i++) {
	index1 = lowerindex+UsefulRoutines.randomInt(candidates);
	index2 = lowerindex+UsefulRoutines.randomInt(candidates);
	if (((RKUValuation)sources[index1]).value()<=((RKUValuation)sources[index2]).value())
	  destination[i] = ((RKUCloneable)(sources[index1])).clone();
	else
	  destination[i] = ((RKUCloneable)(sources[index2])).clone();
      }
    }
    return destination;
    };


}
